package org.jkp.kirtan.finder;

import java.io.Console;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Scanner;
import java.util.Map;
import java.util.LinkedHashMap;

import org.apache.log4j.Logger;

import jxl.Sheet;
import jxl.Workbook;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jkp.mp3tag.BookCode;
import com.jkp.mp3tag.FolderTraverser;
import com.jkp.mp3tag.Kirtan;
import com.jkp.mp3tag.MasterLibrary;
import com.jkp.mp3tag.command.PrintFileNameCommand;

public class OfficialTitleCache {
	
	Logger log = Logger.getLogger(MasterLibrary.class);
	
	private String[] officalTitles = null;
	private static OfficialTitleCache cache = new OfficialTitleCache();
	private List<Kirtan> kirtanList = new ArrayList<Kirtan>();
	private Map<String, String> legend = new LinkedHashMap<String, String>();


	public String officialTitlesSheetFileName = "\\resources\\OfficialTitles.xls";
	
	public String OfficialTitleTemplateJavaFile = "\\OfficialTitleTemplate.java";
	public String OfficialTitleGeneratedJavaFile = "\\OfficialTitleGenerated.java";
	public String OfficialTitleGeneratedJSONFile = "\\web2\\OfficialTitleGenerated.json";
	public static OfficialTitleCache getInstance() {
		if(cache.officalTitles == null){
			cache.initialize();
		}
		return cache;
	}

	public List<Kirtan> getKirtanList() {
		return kirtanList;
	}

	public void setKirtanList(List<Kirtan> kirtanList) {
		this.kirtanList = kirtanList;
	}

	private void initialize() {
		
	    String userDir = System.getProperty("user.dir");
	    String generatedFilePath=userDir + "\\src\\java\\" + this.getClass().getPackage().getName().replace(".", "\\");
	    officialTitlesSheetFileName = userDir + officialTitlesSheetFileName; 
	    OfficialTitleTemplateJavaFile = generatedFilePath + OfficialTitleTemplateJavaFile;
	    OfficialTitleGeneratedJavaFile = generatedFilePath + OfficialTitleGeneratedJavaFile;
	    OfficialTitleGeneratedJSONFile = userDir + OfficialTitleGeneratedJSONFile;
	    
	    List<Kirtan> kirtanList = loadFromFile(officialTitlesSheetFileName);
		kirtanList.addAll(kirtanList);
		officalTitles = new String[kirtanList.size()];
		int i = 0;
		for(Kirtan kirtan: kirtanList){
			officalTitles[i] = kirtan.getTitle();
			i++;
		}
		this.setKirtanList(kirtanList);
		

	}

	public List<Kirtan> loadFromFile(String inFile) {
		List<Kirtan> kirtanList = new ArrayList<Kirtan>();
		Workbook readWorkBook = null;
		Map<String, String> legend = new LinkedHashMap<String, String>();
		
		File inputWorkbook = new File(officialTitlesSheetFileName);
		Kirtan kirtan = null;

		try {
			readWorkBook = Workbook.getWorkbook(inputWorkbook);
			Sheet sheet =	readWorkBook.getSheet(1);
			String title,modTitle,bookCodeStr = null;
			int rowCount = sheet.getRows();
			BookCode bookCode = null;
			
			for(int l = 1; l < rowCount; l++)
			{
				 legend.put(sheet.getCell(1, l).getContents().toUpperCase().toString(), sheet.getCell(0, l).getContents().toString());
			}

			sheet=readWorkBook.getSheet(0);
			rowCount = sheet.getRows();
			for (int r = 1; r < rowCount; r++) {
				title = sheet.getCell(11, r).getContents();
				bookCodeStr = sheet.getCell(10, r).getContents();
				kirtan = new Kirtan();
				if(title !=null){
					title = title.toLowerCase();
					kirtan.setTitle(title);	
				}
				bookCode = new BookCode();
				String[] kirtanDetails = title.split("_");
				modTitle = kirtanDetails[0].substring(0, 1).toUpperCase() + kirtanDetails[0].substring(1).toLowerCase();
				
				System.out.println(kirtanDetails.length);
				System.out.println(legend.containsKey(kirtanDetails[1].toUpperCase()));
				String bookAbbrev = kirtanDetails[1].toString().toUpperCase();
				bookCode.setBookName(legend.get(bookAbbrev));

				
				
				if ((kirtanDetails[1].equalsIgnoreCase("pr1")) || (kirtanDetails[1].equalsIgnoreCase("pr2")))
				{
					
					String other = legend.get(kirtanDetails[2].toString().toUpperCase());
					bookCode.setOther(other);
					bookCode.setPageNum(kirtanDetails[3]);
					bookCode.setPadNum(kirtanDetails[4]);
					if (kirtanDetails.length > 5){
						bookCode.setSecBookName(kirtanDetails[5]);
						bookCode.setSecPageNum(kirtanDetails[6]);
						if (kirtanDetails.length > 7)
							bookCode.setSecPadNum(kirtanDetails[7]);
						 else bookCode.setSecPadNum("");
					}
					else {					
						bookCode.setSecBookName("");
						bookCode.setSecPageNum("");
						bookCode.setSecPadNum("");
					}
				} else
				{
					bookCode.setOther("");
					bookCode.setPageNum(kirtanDetails[2]);			
					if (kirtanDetails.length > 3) {
						bookCode.setPadNum(kirtanDetails[3]);
						if (kirtanDetails.length > 4){
							bookCode.setSecBookName(kirtanDetails[4]);
							bookCode.setSecPageNum(kirtanDetails[5]);
							if (kirtanDetails.length > 6)
								bookCode.setSecPadNum(kirtanDetails[6]);
							else
								bookCode.setSecPadNum("");
						} else{
							bookCode.setPadNum("");
							bookCode.setSecBookName("");
							bookCode.setSecPageNum("");
							bookCode.setSecPadNum("");
						}
					}
					else{
						bookCode.setPadNum("");
						bookCode.setSecBookName("");
						bookCode.setSecPageNum("");
						bookCode.setSecPadNum("");
					}
				}
				
				bookCode.setCode(bookCodeStr);
				kirtan.setTitle(title);
				kirtan.setModTitle(modTitle);
				kirtan.setBookCode(bookCode);
				kirtanList.add(kirtan);
			}			
			readWorkBook.close();			
			
		} catch(Exception ex){
			log.error(ex,ex);
			System.out.println(kirtan.getTitle());
		}		
		return kirtanList;
	}

	public String[] getOfficalTitles() {
		return officalTitles;
	}

	public void setOfficalTitles(String[] officalTitles) {
		this.officalTitles = officalTitles;
	}

	public void generateJavaFile() throws IOException {
		FileReader reader = new FileReader (OfficialTitleTemplateJavaFile);
		PrintWriter writer = new PrintWriter(OfficialTitleGeneratedJavaFile, "UTF-8");
		Scanner input = new Scanner (reader);
		writer.println("/**  This is a generated file and should never be modified manually. To Generate this file");
		writer.println("     , run OfficalTitleCache main method. This method will take titles from excel sheet and");
		writer.println("     populate this class. Whenever the master excel sheet changes, this method should be run **/");
		
		while (input.hasNextLine())
		{
			String line = input.nextLine();
			line = process(line);	
			writer.println(line);
		}
		input.close();
		reader.close();
		writer.close();
		
	}

	private String process(String line) {
		
		if(line.contains("OfficialTitleTemplate")){
			return line.replace("OfficialTitleTemplate", "OfficialTitleGenerated");
		}
		
		if(!line.contains("GeneratedValues")){
			return line;
		}
		
		StringBuilder builder = new StringBuilder();
		if(officalTitles == null){
			cache.initialize();
		}
		
		for(int i = 0; i <officalTitles.length-1; i++){
			builder.append("\"").append(officalTitles[i]).append("\",\n");
		}
		
		builder.append("\"").append(officalTitles[officalTitles.length-1]).append("\"");
		return line.replace(line,builder.toString() );
		
	}
	
	
	public static void main(String args[]) throws Exception {
		OfficialTitleCache cache = OfficialTitleCache.getInstance();
		cache.generateJavaFile();
		cache.generateJSONFile();
	}

	public void generateJSONFile() throws Exception {

		PrintWriter writer = new PrintWriter(OfficialTitleGeneratedJSONFile, "UTF-8");
		//writer.println("/**  This is a generated file and should never be modified manually. To Generate this file");
		//writer.println("     , run OfficalTitleCache main method. This method will take titles from excel sheet and");
		//writer.println("     populate this class. Whenever the master excel sheet changes, this method should be run **/");
		int i=0;
		try {	
			String jsonLine ="[" + "\n";                                        
			String title;
			List<Kirtan> kirtanList = new ArrayList<Kirtan>();
			kirtanList = this.getKirtanList();
			BookCode bookCode = null;
			for(Kirtan kirtan: kirtanList){
				i++;
				
				title=kirtan.getModTitle();
				bookCode = kirtan.getBookCode();
											
				jsonLine += "{\"" + "title\": \"" + title + "\", " + "\n"; 
				jsonLine += "\"bookName\": \"" + bookCode.getBookName() + "\", " + "\n";
				jsonLine += "\"pageNum\": \"" + bookCode.getPageNum() + "\", " + "\n";
				jsonLine += "\"padNum\": \"" + bookCode.getPadNum() + "\", " + "\n";
				jsonLine += "\"secBookName\": \"" + bookCode.getSecBookName() + "\", " + "\n";
				jsonLine += "\"secPageNum\": \"" + bookCode.getSecPageNum() + "\", " + "\n";
				jsonLine += "\"secPadNum\": \"" + bookCode.getSecPadNum() + "\", " + "\n";
				jsonLine += "\"other\": \"" + bookCode.getOther() + "\"" + "\n";
				
				//Can add other fields from Kirtan to Generated JSON file here in future if needed
				
				if (i < kirtanList.size()) {
					jsonLine += "},";
				}
				else
					jsonLine += "}]"; //last line			
				writer.println(jsonLine);			
				jsonLine =""; //reset
			}
			writer.close();
		} catch(Exception ex){
			log.error(ex,ex);
		}		
		
	}

}
